import 'dart:async';
import 'dart:io';

import 'package:bluetooth_protocols_parser_plugin/src/tools/utils.dart';

// 文件工具类
class FileUtils {
  // MARK: - 计算本地文件crc32
  /// [filePath] 文件路径
  /// [offset] 起始偏移量
  /// [length] 计算到的偏移量
  static Future<int> calculateFileCrc32(
    String filePath,
    int offset,
    int length,
  ) async {
    try {
      final file = File(filePath);

      // 检查文件是否存在
      if (!await file.exists()) {
        throw FileSystemException('文件不存在: $filePath');
      }

      // 获取文件大小
      final fileLength = await file.length();

      // 验证参数有效性
      if (offset < 0 || offset >= fileLength) {
        throw ArgumentError('偏移量超出文件范围: $offset, 文件大小: $fileLength');
      }

      if (length <= 0) {
        throw ArgumentError('长度必须大于0: $length');
      }

      // 计算实际读取长度
      final actualLength =
          (offset + length > fileLength) ? fileLength - offset : length;

      // 打开文件并读取指定范围的数据
      final randomAccessFile = await file.open(mode: FileMode.read);
      try {
        await randomAccessFile.setPosition(offset);
        final buffer = await randomAccessFile.read(actualLength);
        return Utils.calCrc32(buffer);
      } finally {
        await randomAccessFile.close();
      }
    } catch (e) {
      throw Exception('计算CRC32失败: $e');
    }
  }

  // MARK: - 计算整个文件crc32
  /// [filePath] 文件路径
  /// 返回值: (文件大小, CRC32值)
  static Future<(int, int)> calculateFullFileCrc32(String filePath) async {
    try {
      final file = File(filePath);

      // 检查文件是否存在
      if (!await file.exists()) {
        throw FileSystemException('文件不存在: $filePath');
      }

      // 获取文件大小
      final fileLength = await file.length();

      // 使用现有的calculateFileCrc32函数，从0开始读取整个文件
      return (fileLength, await calculateFileCrc32(filePath, 0, fileLength));
    } catch (e) {
      throw Exception('计算文件CRC32失败: $e');
    }
  }
}
